package com.sservice.service.service.impl;

import com.sservice.banfu.mapper.SalePersonMapper;
import com.sservice.banfu.service.SalePersonService1;
import com.sservice.banfu.vo.SalePersonVo;
import com.sservice.base.StringUtils;
import com.sservice.base.entity.dto.BaseResult;
import com.sservice.common.Code;
import com.sservice.common.Constants;
import com.sservice.common.OrderConstants;
import com.sservice.commonBusiness.e.Category;
import com.sservice.commonBusiness.e.DataR;
import com.sservice.commonBusiness.mapper.DataRMapper;
import com.sservice.commonBusiness.service.CategoryService;
import com.sservice.commonBusiness.type1.DataR_TYPE;
import com.sservice.commonBusiness.vo.CategoryVo;
import com.sservice.model.dao.*;
import com.sservice.model.entity.*;
import com.sservice.model.vo.InfoVo;
import com.sservice.model.vo.OfferVo;
import com.sservice.model.vo.OrderShopVo;
import com.sservice.model.vo.OrderVo;
import com.sservice.model.wx.Template;
import com.sservice.model.wx.TemplateParam;
import com.sservice.service.common.AdvancedUtil;
import com.sservice.service.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service
@Transactional
public class OrderServiceImpl implements IOrderService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private IOrderDao dataDao;
    @Autowired
    private OrderShopService orderShopService;
    @Autowired
    private IOfferDao offerDao;
    @Autowired
    private SalePersonMapper salePersonMapper;
    @Autowired
    private SalePersonService1 salePersonService1;
    @Autowired
    private ISaleLevelService saleLevelDao;
    @Autowired
    private ISalePersonAccountService spaService;
    @Autowired
    private UserWxMapper userWxDao;

    @Autowired
    private OrderPayDetailMapper opdDao;

    @Autowired
    private ISalePersonAccountDao spaDao;
    @Autowired
    OrderShopMapper orderShopMapper;
    @Autowired
    CategoryService categoryService;
    @Autowired
    DataRMapper dataRMapper;
    @Autowired
    IOfferService offerService;
    @Autowired
    IInfoService infoService;
    @Autowired
    IInfoDao iInfoDao;

    @Override
    public Order selectOneByNo(String no) {
        return dataDao.selectOneByNo(no);
    }

    public OrderServiceImpl() {
    }

    /**
     * 付款佣金
     *
     * @param arg
     */
    @Override
    public BigDecimal payCommission(Order arg) {
        OrderShop orderShop = new OrderShop();
        orderShop.setSpId(arg.getSaleId());
        orderShop.setOrderId(arg.getId().toString());
        List<OrderShop> list = orderShopService.getOrderShopBy(orderShop);
        BigDecimal total = BigDecimal.ZERO;
        for (OrderShop orderShop1 : list) {
            Offer offer = offerDao.selectByPrimaryKey(Integer.valueOf(orderShop1.getOfferId()));
            total = total.add(offer.getActualPrice().multiply(BigDecimal.valueOf(0.05)));
        }
        return total;
    }

//    @Autowired
//    WxPayService wxPayService;

    @Transactional
    public Object cancelOrder(String orderId) {
        Order order = this.selectByPrimaryKey(Integer.valueOf(orderId));
        if (!"order".equals(order.getType1())) {
            order.setPayStatus("-1");
            dataDao.updateByPrimaryKeySelective(order);
            return "退款完成";
        }
        if (!"0".equals(order.getStatus())) { //
            return "订单已不满足退款条件，已经取消或完成";
        }
        if ("0".equals(order.getPayStatus())) { // 超时未付费
            order.setStatus("-2");// 订单超时未付费
        } else if ("1".equals(order.getPayStatus())) {
            order.setStatus("-1");// 付款回退

        }
        return dataDao.updateByPrimaryKeySelective(order);
    }

    /**
     * 支付成功
     *
     * @param arg
     * @return
     */
    @Override
    @Transactional
    public BaseResult paySuccess(OrderVo arg) {

        Order order = dataDao.selectOneByNo(arg.getNo());
        if (order == null || !arg.getSaleId().equals(order.getSaleId())) {
            return new BaseResult(false, "操作失败", Code.ACTION_FAILD);
        }
        if ("1".equals(order.getPayStatus())) {
            return new BaseResult(false, "订单已经支付", Code.REPEAT_ACTION);
        }

        if (order.getBusinessId().equals(OrderVo.TYPE_JOIN_GROUP_BUY)) { // 加入拼团
            DataR dataR = new DataR();
            dataR.setType1(OrderVo.DATA_R_GROUP);
            dataR.setTargetId(order.getId());
            List<DataR> dataR1 = dataRMapper.selectBy(dataR);
            if (dataR1.size() == 1) {//更新拼团状态
                Integer groupId = dataR1.get(0).getSourceId();
                Category group = categoryService.selectByPrimaryKey(groupId);//
                if (group != null) {
                    group.setStatus(OrderVo.STATUS_GROUP_FINISHED);//
                    categoryService.updateByPrimaryKeySelective(group);//
                }
            }
        }
        order.setTransactionId(arg.getTransactionId());
        order.setTotal(order.getTotal());
        order.setPayStatus("1");// 支付成功
        dataDao.updateByPrimaryKeySelective(order);
        return new BaseResult(true, order);
    }


    @Override
    public Integer countPlainByPage(OrderVo user) {
        return dataDao.countPlainByPage(user);
    }

    @Override
    public List<OrderVo> queryPlainByPage(OrderVo user) {
        return dataDao.queryPlainByPage(user);
    }

    /**
     * 用户礼品卡、优惠券查询
     *
     * @param arg
     * @return
     */
    @Override
    public List<CategoryVo> queryCategory(CategoryVo arg) {
        return dataDao.queryCategoryByCondition(arg);
    }

    /**
     * 激活礼品卡
     * arg.en 卡号
     * arg.sys_id 用户Id
     *
     * @param arg
     * @return
     */
    @Override
    @Transactional
    public Object queryGift(Category arg) {
        Category category = new Category();
        String label = "兑换号";
        if (OrderVo.CARD_GIFT.equals(arg.getType1())) {
            label = "卡号";
        }
        category.setType1(arg.getType1());
        category.setEn(arg.getEn());//卡号
        List<Category> categoryList = categoryService.selectListBy(category);
        if (categoryList.size() == 0) {
            return label + "不存在";
        }
        if (categoryList.size() != 1) {
            return "该" + label + "存在异常，不能兑换";
        }
        category = categoryList.get(0);
        category.setRemark("已兑换");
        categoryService.updateByPrimaryKeySelective(category);
        DataR dataR = new DataR();
        dataR.setType1(OrderVo.CARD_GIFT.equals(arg.getType1()) ?
                DataR_TYPE.TYPE_GIFT.getValue()
                : DataR_TYPE.TYPE_COUPON.getValue());// 礼品兑换
        dataR.setSourceId(Integer.valueOf(arg.getSysId()));//兑换用户ID
        dataR.setTargetId(category.getId());
        List<DataR> list = new ArrayList();
        if (OrderVo.CARD_GIFT.equals(arg.getType1())) {// 礼品卡兑换
            list = dataRMapper.selectBy(dataR);
            if (list.size() == 1) throw new RuntimeException("已兑换");
            if (list.size() > 1) throw new RuntimeException("兑换错误");
        }
        list.clear();
        list.add(dataR);
        dataRMapper.addBatch(list);

        return null;
    }


    @Override
    public Map detail(int id, String no) {
        Order order = null;
        if (StringUtils.isNoneBlank(no)) order = this.selectOneByNo(no);
        if (id != 0) order = this.selectByPrimaryKey(id);
        Map orderMap = new HashMap();
        orderMap.put("order", order); // 订单详情
        OrderShop orderShop = new OrderShop();
        orderShop.setSpId(order.getSaleId());
        orderShop.setOrderId(order.getId().toString());
        orderShop.setType1("order");// 订单数据
        List orderItems = dataDao.selectShopCartItems(orderShop);
        orderMap.put("orderItem", orderItems);
        return orderMap;
    }


    @Override
    public Map exchangeDetail(int id, String no) {
        Order order = null;
        if (StringUtils.isNoneBlank(no)) order = this.selectOneByNo(no);
        if (id != 0) order = this.selectByPrimaryKey(id);
        Map orderMap = new HashMap();
        orderMap.put("order", order); // 订单详情
        Offer offer = offerService.selectByPrimaryKey(Integer.valueOf(order.getOfferId()));
        orderMap.put("offer", offer); // 订单详情
        return orderMap;
    }

    @Override
    public Map serviceDetail(int id, String no) {
        Order order = null;
        if (StringUtils.isNoneBlank(no)) order = this.selectOneByNo(no);
        if (id != 0) order = this.selectByPrimaryKey(id);
        Map orderMap = new HashMap();
        orderMap.put("order", order); // 订单详情
        orderMap.put("serviceItems", getServiceShop(order.getId(), "service"));       // 服务详情
        return orderMap;
    }

    @Override
    public Map orderDetail(int id, String no) {
        Order order = null;
        if (StringUtils.isNoneBlank(no)) order = this.selectOneByNo(no);
        if (id != 0) order = this.selectByPrimaryKey(id);
        Map orderMap = new HashMap();
        orderMap.put("order", order);                                                   // 订单详情
        orderMap.put("orderItems", getOrderShop(order.getId(), "order", order.getSaleId()));           // 订单项详情
        return orderMap;
    }

    List<OrderShop> getOrderShop(Integer orderId, String type, String ownerId) {
        OrderShop orderShop = new OrderShop();
        orderShop.setType1(type);
        orderShop.setOrderId(String.valueOf(orderId));
        orderShop.setSpId(ownerId);
        return orderShopService.getOrderShopBy(orderShop);

    }

    List<InfoVo> getServiceShop(Integer orderId, String type) {
        InfoVo infoVo = new InfoVo();
        infoVo.setServiceType1(type);
        infoVo.setOrderId(String.valueOf(orderId));
        List<InfoVo> offer = iInfoDao.queryWithOrderShopByPage(infoVo);
        return offer;

    }

    @Override
    public Object exchange(OrderVo arg) {
        arg.setNo(Constants.generateDataNo("NC", "M", arg.getSaleId()));
        return dataDao.insertSelective(arg);
    }

    @Override
    public Object shopItemCheck(OrderShop arg, String ids) {
        if ("2".equals(arg.getType1()) && StringUtils.isNoneBlank(arg.getSpId())) {// 全选
            OrderShop orderShop = new OrderShop();
            orderShop.setThemeId(arg.getThemeId());
            orderShop.setType1("cart");
            orderShop.setSpId(arg.getSpId());
            orderShop.setStatus(arg.getStatus());
            orderShopMapper.updateBy(orderShop);
        }
        if ("3".equals(arg.getType1()) && StringUtils.isNoneBlank(arg.getSpId()) && StringUtils.isNoneBlank(ids)) {// 全选
            OrderShop orderShop = new OrderShop();
            orderShop.setThemeId(arg.getThemeId());
            orderShop.setType1("cart");
            orderShop.setSpId(arg.getSpId());
            orderShop.setStatus(arg.getStatus());
            for (String id : ids.split(",")) {
                OrderShop orderShop1 = new OrderShop();
                orderShop1.setStatus(arg.getStatus());
                orderShop1.setId(Integer.valueOf(id));
                orderShopMapper.updateByPrimaryKeySelective(orderShop1);
            }
            return ids.split(",").length;
        }
        OrderShop orderShop = new OrderShop();
        OrderShop o = orderShopMapper.selectByPrimaryKey(arg.getId());
        if (o != null && (arg.getSpId()).equals(o.getSpId())) {
            orderShop.setStatus(arg.getStatus()); // 购物车中物品选中状态
            orderShop.setId(arg.getId());
            return orderShopMapper.updateByPrimaryKeySelective(orderShop);
        } else {
            return "参数错误";
        }
    }

    @Override
    public List<OrderVo> queryByPage(OrderVo user) {
        return dataDao.queryByPage(user);
    }

    @Override
    public List<OrderVo> queryByPage(OrderVo arg, List list) {
        return dataDao.queryByPage(arg, list);
    }

    @Override
    public List<OrderVo> selectPcByThemeId(OrderShopVo orderShop) {
        return dataDao.selectPcByThemeId(orderShop);
    }

    @Override
    public List<OrderVo> selectOngoingPcByThemeId(String themeId, String sizeId) {
        OrderShopVo orderShopVo = new OrderShopVo();
        orderShopVo.setOngoing("1"); //
        orderShopVo.setThemeId(themeId);
        orderShopVo.setSizeId(sizeId);
        return dataDao.selectPcByThemeId(orderShopVo);
    }


    @Override
    public boolean sendPayedTmpMsg(String first, BigDecimal orderTotal, String detail, String orderAddress, String orderNo, String remark, String toUser) {
        Template tem = new Template();
        tem.setTemplateId(Constants.tmplOrderPaySuccess); // 付款成功
        tem.setTopColor("#00DD00");
        tem.setToUser(toUser);
        tem.setUrl(Constants.domain + "/wx/user/index.html");
        List<TemplateParam> paras = new ArrayList<TemplateParam>();
        paras.add(new TemplateParam("first",
                first, "#333333"));
        paras.add(new TemplateParam("orderProductPrice", Constants.format2Double(orderTotal.doubleValue()), "#333333"));
        paras.add(new TemplateParam("orderProductName", detail, "#333333"));
        paras.add(new TemplateParam("orderAddress", orderAddress, "#333333"));
        paras.add(new TemplateParam("orderName", orderNo, "#333333"));
        paras.add(new TemplateParam("remark", "查看订单详情!", "#333333"));
        tem.setTemplateParamList(paras);
        AdvancedUtil.senderTmplSms(tem);
        return false;
    }

    @Override
    public int queryCount(OrderVo user, List list) {
        return dataDao.queryCount(user, list);
    }

    @Override
    public List<OrderVo> queryMyOrdersByPage(OrderVo user) {
        return dataDao.queryMyOrdersByPage(user);
    }


    @Override
    public int deleteByPrimaryKey(Integer id) {
        return dataDao.deleteByPrimaryKey(id);
    }

    @Override
    public int insert(Order record) {
        return dataDao.insert(record);
    }

    @Override
    public int insertSelective(Order record) {
        return dataDao.insertSelective(record);
    }

    @Override
    public Order selectByPrimaryKey(Integer id) {
        return dataDao.selectByPrimaryKey(id);
    }

    @Override
    public int updateByPrimaryKeySelective(Order record) {
        return dataDao.updateByPrimaryKeySelective(record);
    }


    public Double judgeLevel(Double cashTotal) {
        List<SaleLevel> list = saleLevelDao.selectAll();
        Map<String, Double> map = new HashMap<String, Double>();

        for (SaleLevel sl : list) {
            map.put(String.valueOf(sl.getLevel()).trim(), sl.getPercent());
        }
        Double coefficient = 0.0;
        if (cashTotal < 500) {
            coefficient = map.get("500");
        } else if (cashTotal < 5000) {
            coefficient = map.get("5000");
        } else if (cashTotal < 20000) {
            coefficient = map.get("20000");
        } else if (cashTotal < 50000) {
            coefficient = map.get("50000");
        } else if (cashTotal < 100000) {
            coefficient = map.get("100000");
        } else if (cashTotal < 200000) {
            coefficient = map.get("200000");
        } else if (cashTotal < 400000) {
            coefficient = map.get("400000");
        } else if (cashTotal < 700000) {
            coefficient = map.get("700000");
        } else if (cashTotal < 1000000) {
            coefficient = map.get("1000000");
        }

        return coefficient;
    }

    /**
     * 订单审核
     *
     * @param arg
     * @return
     */
    @Override
    public Object checkOrder(Order arg) {
        return dataDao.updateByPrimaryKeySelective(arg);
    }


    /**
     * 更新订单实际成交价格
     *
     * @param arg
     * @return
     */
    @Override
    public Object updatePrice(Order arg) {
        Order order = dataDao.selectByPrimaryKey(arg.getId());
        if ("1".equals(order.getCheckStatus())) {
            return "订单已经审核,无法修改!";
        }
        if ("1".equals(order.getPayStatus())) {
            return "订单已经付款,无法修改!";
        }
        arg.setActualTotal(arg.getActualPrice().multiply(order.getNumber()));
        int res = dataDao.updateByPrimaryKeySelective(arg);
        if (res > 0) { // tmpl msg notice
            SalePersonVo salep = salePersonService1.selectByPrimaryKey(Integer.valueOf(order.getSaleId()));
            if (salep.getOpenid() != null) {
                UserWx uw = new UserWx();
                uw.setUnionid(salep.getOpenid());
                uw.setUnitid(Constants.WXUserTypeWX);
                UserWx ux1 = userWxDao.selectByUnionid(uw);
                if (ux1 != null) {
                    Template tem = new Template();
                    tem.setTemplateId(Constants.tmplUpdateOrderPrice);
                    tem.setTopColor("#00DD00");
                    tem.setToUser(ux1.getOpenid());
                    tem.setUrl(Constants.domain + "/wx/user/order.html");
                    List<TemplateParam> paras = new ArrayList<TemplateParam>();
                    paras.add(new TemplateParam("first",
                            "您好，你购买的订单号为" + order.getNo() + "的商品价格已被卖家调整，请去我的订单查看。", "#333333"));
                    paras.add(new TemplateParam("keyword1", order.getNo(), "#666666"));
                    paras.add(new TemplateParam("keyword2", Constants.format2Double(order.getPrice().doubleValue()), "#666666"));
                    paras.add(new TemplateParam("keyword3", Constants.format2Double(arg.getActualPrice().doubleValue()), "#666666"));
                    paras.add(new TemplateParam("backupFieldData", arg.getGoodsName(), "#666666"));
                    paras.add(new TemplateParam("remark", "请注意价格调整!", "#666666"));
                    tem.setTemplateParamList(paras);
                    AdvancedUtil.senderTmplSms(tem);
                }
            }
        }
        return res;
    }

    @Autowired
    AddressService addressService;

    /**
     * 发起拼团
     *
     * @param num num人拼团，
     * @param num num人拼团，
     */
    Category setupGroup(int num, Date date, String saleId) {
        Category category = new Category();
        category.setType1(OrderVo.DATA_R_GROUP);// 拼团类型
        category.setStatus(OrderVo.STATUS_GROUP_GOING);// 默认拼团进行中
        category.setTotal(BigDecimal.valueOf(num));//num 人团
        category.setLevel("1");//已参团人数
        category.setValidEnd(date);// 拼团截止日期
        category.setEn(Constants.generateGroupNo(saleId));
        categoryService.insertSelective(category);
        return category;
    }

    /**
     * 1. 单商品购买
     * 主题页发起拼团和直接购买多个商品
     *
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Object createOrderByThemeId(OrderVo arg) {

        OrderShop orderShop = new OrderShop();
        orderShop.setSpId(arg.getSaleId());
        orderShop.setThemeId(arg.getThemeId());
        if (StringUtils.isBlank(arg.getThemeId())) {// 主题ID为null或多主题情况，默认购物车中选中商品结算
            orderShop.setStatus("1");
            orderShop.setThemeId(null);
        }
        List<OrderShop> list = orderShopService.getOrderShopBy(orderShop);//
        if (list.size() == 0) {
            if (StringUtils.isBlank(arg.getShopIds())) {
                return "数据异常，或订单已经处理";
            } else {
                list = new ArrayList();
                list.add(orderShopService.findById(Integer.valueOf(arg.getShopIds())));//
            }
        }
        BigDecimal total = BigDecimal.ZERO;
        Integer joinOrderId = 0;
        Category category = null;// 拼团对象
        // 商品信息
        if (OrderVo.TYPE_CREATE_GROUP_BUY.equals(arg.getType())) {
            arg.setBusinessId(OrderVo.TYPE_CREATE_GROUP_BUY); // 发起拼团
            category = setupGroup(2, new Date(System.currentTimeMillis() - 24 * 1000 * 60 * 60), arg.getSaleId());//
        } else if (OrderVo.TYPE_MULTI_ORDER_BUY.equals(arg.getType())) {
            arg.setBusinessId(OrderVo.TYPE_MULTI_ORDER_BUY); //多商品购买
        }
        if (OrderVo.TYPE_SINGLE_OFFER_BUY.equals(arg.getType())) { //拼团单商品购买
            arg.setBusinessId(OrderVo.TYPE_SINGLE_OFFER_BUY);
        } else if (OrderVo.TYPE_SINGLE_OFFER_NO_PT_BUY.equals(arg.getType())) { // 非拼团单商品直接购买
            arg.setBusinessId(OrderVo.TYPE_SINGLE_OFFER_NO_PT_BUY); //
        } else if (OrderVo.TYPE_JOIN_GROUP_BUY.equals(arg.getType())) {
            arg.setBusinessId(OrderVo.TYPE_JOIN_GROUP_BUY); //多商品购买
        }
        arg.setNumber(BigDecimal.valueOf(list.stream().mapToDouble(p -> p.getNumber()).sum()));// 商品数量

        //  地址信息
        Address address = addressService.findById(Integer.valueOf(arg.getAddressId()));
        arg.setAddress(address.getPerson() + "," + address.getPhone() + ","
                + address.getProvince()
                + address.getCity()
                + address.getRegion()
                + address.getDetail()
        );
        Offer offer1 = offerDao.selectByPrimaryKey(Integer.valueOf(list.get(0).getOfferId()));
        arg.setDeliverPlace(offer1.getDeliverPlace()); // 设置供货地
        arg.setActualTotal(arg.getPayTotal());
        Order order = this.insertOrder(arg);// 创建订单
        if (OrderVo.TYPE_CREATE_GROUP_BUY.equals(arg.getType())) {// 发起拼团
            if (category != null) {
                List drList = new ArrayList();
                DataR dataR = new DataR();
                dataR.setType1(OrderVo.DATA_R_GROUP);
                dataR.setTargetId(order.getId());
                dataR.setSourceId(category.getId());// 拼团号ID
                drList.add(dataR);
                dataRMapper.addBatch(drList);
            }
        } else if (OrderVo.TYPE_JOIN_GROUP_BUY.equals(arg.getType())) {//// 标记两个订单属于同一个拼团
            DataR dataR = new DataR();
            dataR.setTargetId(joinOrderId);
            dataR.setType1(OrderVo.DATA_R_GROUP);
            List<DataR> existGroup = dataRMapper.selectBy(dataR);
            if (existGroup.size() != 1) throw new RuntimeException("加入拼团失败");
            List drList = new ArrayList();
            DataR dataR2 = new DataR();
            dataR2.setType1(OrderVo.DATA_R_GROUP);// 拼单号
            dataR2.setTargetId(order.getId());
            dataR2.setSourceId(existGroup.get(0).getSourceId());
            drList.add(dataR2);
            dataRMapper.addBatch(drList);

            // 拼团信息更新
            Category category1 = categoryService.selectByPrimaryKey(existGroup.get(0).getSourceId());
            BigDecimal groupedMember = BigDecimal.valueOf(Integer.valueOf(category1.getLevel()));
            if (groupedMember.compareTo(category1.getTotal()) != -1) throw new RuntimeException("加入拼团失败");
            groupedMember = BigDecimal.ONE.add(groupedMember);
            category1.setLevel(groupedMember.toString());//
            if (groupedMember.compareTo(category1.getTotal()) == 0) {// 拼团结束
                category1.setStatus(OrderVo.STATUS_GROUP_FINISHED);
            }
            categoryService.updateByPrimaryKeySelective(category1);
        }

        BigDecimal totalPreferential = BigDecimal.ZERO;
        // 购物车中商品条目项变更
        for (OrderShop orderShop1 : list) {
            Offer offer = null;
            if (orderShop1.getOfferId().equals(offer1.getId().toString())) {
                offer = offer1;
            } else {
                offer = offerDao.selectByPrimaryKey(Integer.valueOf(orderShop1.getOfferId()));
            }
            OfferVars offerVars = new OfferVars();
            offerVars.setOfferId(offer.getId().toString());
            offerVars.setVars(orderShop1.getSizeId());
            OfferVars offerVars1 = offerVarsMapper.selectOneBy(offerVars);
            BigDecimal price = BigDecimal.ZERO;
            if ("1".equals(offer.getStatusPt())) {// 参与拼团活动的商品以拼团价计算
                price = offerVars1.getPtPrice();
                BigDecimal su = offerVars1.getActualPrice().subtract(offerVars1.getPtPrice());
                totalPreferential = totalPreferential.add(su.multiply(BigDecimal.valueOf(orderShop1.getNumber())));
            } else {
                price = offerVars1.getActualPrice();
            }
            total = total.add(price.multiply(BigDecimal.valueOf(orderShop1.getNumber())));// 合计总额
            orderShop1.setPrice(price);// 成交价格
            orderShop1.setType1("order");
            orderShop1.setOrderId(order.getId().toString());
            orderShopService.update(orderShop1);
        }
        List<DataR> opdList = new ArrayList();
        if (totalPreferential.compareTo(BigDecimal.ZERO) != 0) {//
            // 活动优惠
            DataR preferentialDetail = generatePayDetail(order.getId());
            preferentialDetail.setDesc1("活动优惠," + totalPreferential.doubleValue());
            opdList.add(preferentialDetail);
        }

        if (StringUtils.isNoneBlank(arg.getGift())) {  // 结算使用礼品卡
            arg.setId(order.getId());
            DataR dataR = generatePayDetail(total, arg);
            total = total.subtract(BigDecimal.valueOf(Double.valueOf(dataR.getKeyword())));
            if (dataR != null) opdList.add(dataR);
        }
        if (opdList.size() != 0) dataRMapper.addBatch(opdList);// 插入数据
        if (total.compareTo(arg.getPayTotal()) != 0) {
            throw new RuntimeException("单价总额计算错误");
        }
        return order;
    }


    @Transactional
    private DataR generatePayDetail(BigDecimal total, OrderVo arg) {
//        List<DataR> opdList = new ArrayList();
        DataR dataR = null;
        if (StringUtils.isNoneBlank(arg.getGift())) {// 结算使用礼品卡
            if (total.compareTo(BigDecimal.ZERO) != 1) { // 订单金额不大于0
                throw new RuntimeException("订单结算金额异常");
            }
            dataR = generatePayDetail(arg.getId());
            Category gift = getGift(arg.getGift());// 获取礼品卡
            if (gift == null) throw new RuntimeException("所用礼品卡异常");
            int giftRemain = gift.getTotal().compareTo(total);
            BigDecimal useTotalThisTime = BigDecimal.ZERO;
            if (giftRemain == 1) {
                useTotalThisTime = total;
                gift.setRemark(BigDecimal.valueOf(Double.valueOf(gift.getRemark())).add(total).doubleValue() + "");// 增加已用金额
                gift.setTotal(null);
                categoryService.updateByPrimaryKeySelective(gift);//更新礼品卡
                //total = BigDecimal.ZERO;
            } else if (giftRemain == 0 || giftRemain == -1) {
                useTotalThisTime = gift.getTotal();
                gift.setRemark(BigDecimal.valueOf(Double.valueOf(gift.getRemark())).add(useTotalThisTime).doubleValue() + "");// 增加已用金额
                gift.setStatus(Integer.valueOf(2));// 礼品卡无可用金额
                //total = giftRemain == 0 ? BigDecimal.ZERO : total.subtract(gift.getTotal());
                gift.setTotal(null);// 礼品卡
                categoryService.updateByPrimaryKeySelective(gift);//更新礼品卡
            }
            //dataR.setKeyword(useTotalThisTime.toString());// 付款金额
            dataR.setDesc1("礼品卡," + useTotalThisTime.toString());// 明细项
        }
        return dataR;
    }

    /***
     * 通过礼品卡号获取礼品卡
     * 其中total 为 礼品卡计算后可用金额
     * @param no
     * @return
     */
    private Category getGift(String no) {
        Category category = new Category();
        category.setEn(no);
        category.setType1(OrderVo.CARD_GIFT);//
        Category category1 = categoryService.selectBy(category);
        if (category1 == null) return null; // 找不到该礼品卡
        // 礼品卡状态非正常、或已用金额不小于礼品卡金额
        if (!Integer.valueOf(1).equals(category1.getStatus()) || (BigDecimal.valueOf(Float.parseFloat(category1.getRemark())).compareTo(category1.getTotal())) != -1) {
            return null;
        }
        category1.setTotal(category1.getTotal().subtract(BigDecimal.valueOf(Float.parseFloat(category1.getRemark()))));// 计算可用金额
        return category1;
    }

    // 支付明细基本对象
    private DataR generatePayDetail(Integer orderId) {
        DataR dataR = new DataR();
        dataR.setSourceId(orderId);
        dataR.setType1(OrderVo.DATA_R_ORDER_PAY_DETAIL);
        dataR.setTargetId(0);
        return dataR;
    }

    /**
     * 订单号生成规则
     *
     * @param order
     * @return
     */
    public Order insertOrder(Order order) {
        order.setNo(Constants.generateOrderNo(
                Constants.ORDER_FROM_APP_WXMIN,
                Constants.PAY_TYPE_WX,
                Constants.BUSINESS_TYPE_SHOP,
                order.getSaleId()
        ));
        dataDao.insertSelective(order);
        return order;
    }

    /**
     * 下单
     * arg.shopIds      购买商品Id，多个用逗号分割
     * arg.numbers      购买商品数量，用个用逗号分割
     * arg.type         订单类型
     * arg.total        使用佣金金额
     * arg.payTotal     商品合计金额
     * arg.saleId       下单用户ID
     *
     * @param arg
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public synchronized Object create(OrderVo arg, UserWx userWx) {
        if (StringUtils.isBlank(arg.getShopIds()) && StringUtils.isBlank(arg.getType())) { //非 多商品直接下单、发起拼场
            return "shopIds参数错误或type参数未传递";
        }
        BigDecimal comissionTotal = BigDecimal.ZERO;
        UserWx buyer = null;
        if (arg.getTotal() != null) {                       //佣金结算
            comissionTotal = arg.getTotal();
            buyer = userWxDao.selectByPrimaryKey(Integer.valueOf(arg.getSaleId()));//定
            if ((buyer.getPointsNow()).compareTo(comissionTotal) == -1) {
                return "用户可用佣金余额不足";
            }
        }
        String[] ids = arg.getShopIds().split(",");     // 选择商品ID
        String[] numbers = arg.getNumbers().split(","); // 选择数量

        List<OrderShop> list = new ArrayList();                //

        Order order = new Order();                             // 商品订单
        order.setBusinessId(arg.getType());                    // 订单类型
        order.setActualTotal(BigDecimal.ZERO);                 // 初始化
        if (arg.getAddress() == null) {                        //默认登录信息
            order.setAddress(userWx.getNickName() + " / " + userWx.getPhone());
        }

        order.setSaleId(arg.getSaleId());
        order.setCreateAt(new Date());
        order.setSaleName(arg.getSaleName());                                   //用户昵称
        Offer offer1 = offerDao.selectByPrimaryKey(Integer.valueOf(ids[0]));
        order.setPayStatus("0");                                                // 订单状态，未支付
        order.setType1("order");
        order.setDeliverPlace(offer1.getDeliverPlace());
        BigDecimal totalNumber = BigDecimal.ZERO;
        BigDecimal total = BigDecimal.ZERO;
        for (int i = 0; i < ids.length; i++) { //订单遍历
            OrderShop orderShop1 = new OrderShop();
            orderShop1.setType1(OrderShopVo.TYPE1_CART);
            orderShop1.setOfferId(ids[i]);
            orderShop1.setSpId(arg.getSaleId());
            OrderShop orderShop2 = orderShopService.getOrderShopOneBy(orderShop1); //购物车中已有的商品
            totalNumber = BigDecimal.valueOf(Integer.valueOf(numbers[i])).add(totalNumber);
            orderShop2.setType1("order");                    // 转化为订单,清空购物车中商品
            total = total.add(orderShop2.getPrice().multiply(BigDecimal.valueOf(orderShop2.getNumber())));   // 单项商品小计
            list.add(orderShop2);
        }
        order.setNumber(totalNumber);                      // 订单商品数量小计
        logger.info("[===]", total.intValue());
        if (arg.getSoftDocNum() != 0) {
            total = total.add(BigDecimal.valueOf(Double.valueOf(arg.getSoftDocNum())).multiply(BigDecimal.valueOf(300)));//软著300
        }
        if (total.compareTo(arg.getPayTotal()) != 0) {     //不含佣金
            return "参数计算错误";
        }
        order.setActualNumber(BigDecimal.valueOf(arg.getSoftDocNum()));//代写文档数量
        order.setTotal(arg.getPayTotal());           // 订单商品总价合计
        if (list.size() == 0) return "数据有误";            //
        insertOrder(order);                                // 创建订单
        if (comissionTotal.compareTo(BigDecimal.ZERO) != 0) {
            generateCommissionWithDrawLog(
                    comissionTotal,
                    buyer,
                    "佣金支付订单，订单号：" + order.getNo(),
                    order.getId()
            );
        }
        for (OrderShop o : list) {
            o.setOrderId(order.getId().toString());        // 关联订单
            orderShopService.update(o); //
        }
        return order;
    }

    /**
     * 生成佣金使用记录
     *
     * @param totalUsed 本次使用佣金金额
     * @param user      用户，
     * @param remark    使用说明
     * @param orderId   关联订单ID
     */
    @Transactional
    public void generateCommissionWithDrawLog(
            BigDecimal totalUsed,
            UserWx user,
            String remark,
            Integer orderId
    ) {
        Category comissionLog = new Category();
        comissionLog.setTotal(totalUsed);
        comissionLog.setpId(user.getId().toString());
        comissionLog.setRemark(remark);
        comissionLog.setStatus(1);                         //佣金状态
        comissionLog.setType1(CategoryVo.TYPE_COMMISSION); //
        comissionLog.setValidEnd(new Date());
        user.setPointsNow((user.getPointsNow()).subtract(totalUsed));
        comissionLog.setOrderNum(orderId);//
        userWxDao.updateByPrimaryKeySelective(user);
        categoryService.insertSelective(comissionLog);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public synchronized Object apply(OrderVo arg, UserWx userWx) {
        if (StringUtils.isBlank(arg.getShopIds()) && StringUtils.isBlank(arg.getType())) { //非 多商品直接下单、发起拼场
            return "shopIds参数错误或type参数未传递";
        }
        if (StringUtils.isBlank(arg.getType())) {
            return "参数错误，type必传项";
        }
        String[] ids = arg.getShopIds().split(","); // 选择商品ID
        String[] numbers = arg.getNumbers().split(","); // 选择商品ID

        List<OrderShop> list = new ArrayList();
        Order order = new Order();// 商品订单
        order.setBusinessId(arg.getType());
        order.setType1("service");//服务
        order.setActualTotal(BigDecimal.ZERO);// 初始化
        order.setSaleId(arg.getSaleId());
        order.setCreateAt(new Date());
        if (arg.getAddress() == null) {                        //默认登录信息
            order.setAddress(userWx.getNickName() + " / " + userWx.getPhone());
        }
        for (int i = 0; i < ids.length; i++) { //订单遍历
            OrderShop orderShop = new OrderShop();
            orderShop.setOfferId(ids[i]); //调卷问题
            orderShop.setNumber(1.0);
            orderShop.setSpId(arg.getSaleId());//
            orderShop.setType1("service");
            orderShop.setPrice(BigDecimal.ZERO);//
            orderShop.setBrand(numbers[i]);//答案内容
            list.add(orderShop);
        }
        order.setActualTotal(BigDecimal.ZERO);
        if (list.size() == 0) return "数据有误";//
        insertOrder(order);// 创建订单
        for (OrderShop o : list) {
            o.setOrderId(order.getId().toString());
        }
        orderShopService.addBatch(list);
        return order;
    }


    void log(Exception e) {
        logger.error("[----异常----]" + e.getLocalizedMessage());
        logger.error("[----异常----]" + e.getCause());
        logger.error("[----异常----]" + e.getStackTrace());
        logger.debug("[----异常----]" + e.getMessage());

    }

    /**
     * 发起拼团
     *
     * @param arg
     * @return
     */
    @Override
    public Object createGroupshopping(OrderVo arg) {
        arg.setCode("1");// 标记是否发起拼团
        return create(arg, null);
    }

    /**
     * 加入拼团
     *
     * @param arg
     * @return
     */
    @Override
    public Object joinGroupshopping(OrderVo arg) {
        arg.setCode("2");// 加入拼团
        return create(arg, null);
    }

    @Override
    public Object removeShopCart(OrderShop arg) {
        return orderShopService.removeById(arg.getId());
    }

    @Autowired
    OfferVarsMapper offerVarsMapper;

    /**
     * 加入购物车
     */
    @Transactional(rollbackFor = Exception.class)
    public synchronized Object addShopCart(OrderShop arg) {
        try {
            if (StringUtils.isBlank(arg.getOfferId())) { // 商品ID
                return "offerIds参数错误";
            }
            OrderShop orderShop = new OrderShop();
            orderShop.setSpId(arg.getSpId());
            orderShop.setType1("cart");
            orderShop.setOfferId(arg.getOfferId());//购物车中商品Id
            orderShop.setStatus("11");//不判断是否选中
            List<OrderShop> list = orderShopMapper.getOrderShopBy(orderShop);
            if (list.size() > 0) { // 存在同规格商品
                OrderShop os = list.get(0);
                os.setNumber(os.getNumber() + arg.getNumber());
                return orderShopMapper.updateByPrimaryKeySelective(os);
            }
            Offer offer = offerDao.selectByPrimaryKey(Integer.valueOf(arg.getOfferId()));
            arg.setPrice(offer.getPrice());//单价
            arg.setName(offer.getName());
            arg.setThumbnail(offer.getThumbnail());
            arg.setCreateAt(new Date());
            List<OrderShop> list2 = new ArrayList();
            list2.add(arg);
            if (list2.size() == 0) return "数据有误";
            return orderShopService.addBatch(list2);
        } catch (Exception e) {
            log(e);
            return "服务端异常!";
        }
    }

    public List<OfferVo> getShopCarts(OrderShop arg) {
        return dataDao.getShopCarts(arg);
    }

    /**
     * 强制执行完毕订单时的佣金发放
     *
     * @param orderId
     */

    public void giveActualCommissionForForceEnd(String orderId) {

    }

    /***
     * 销售订单退款至相应的预收款单中
     */
    private synchronized void returnMoney(Order order) {

    }

    /**
     * 强制执行完毕
     * 1. 发放佣金
     * 2. 更新报价相关数据
     * 3. 更新订单相关数据
     * 4. 更新提单相关数据
     *
     * @param arg
     * @return
     */
    @Override
    public Object forceEnd(Order arg) {

        return null;
    }


    @Override
    public synchronized Object applyBack(Order arg) {
        Order order_ = dataDao.selectByPrimaryKey(arg.getId());
        if (order_.getApplyBack().equals("4")) {
            return "销售订单已退款";
        }
        if ("2".equals(order_.getStatus()) || "1".equals(order_.getStatus())) {
        } else {
            return "非强制执行完毕的订单，不能退款!";
        }
        if ("1".equals(order_.getApplyBack())) {
            return "订单已申请退款!";
        }
        Order order = new Order();
        order.setId(arg.getId());
        order.setApplyBack("1");
        dataDao.updateByPrimaryKeySelective(order);
        Map map = new HashMap();
        map.put("orderId", order.getId());
        return 0;
    }

    @Override
    public Object endOrder(Order arg) {
        Order order = dataDao.selectByPrimaryKey(arg.getId());
        if ("0".equals(order.getCheckStatus())) {
            return "订单未审核!";
        }


        return dataDao.updateByPrimaryKeySelective(arg);
    }

    @Override
    public Object payed(Order arg) {
        OrderPayDetail opd = new OrderPayDetail();
        opd.setActualTotal(arg.getActualTotal().doubleValue());
        opd.setOrderId(String.valueOf(arg.getId()));
        opd.setOperator(arg.getOfferId()); //OfferId穿过登录用户ID
        opdDao.insertSelective(opd);
        arg.setOfferId(null);
        return dataDao.updateByPrimaryKeySelective(arg);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer createTest() {
        Order order = new Order();
        Offer of = offerDao.selectByPrimaryKey(27);
        of.setCount(of.getCount() + 1);

        offerDao.updateByPrimaryKeySelective(of);
        if (true) {
            throw new RuntimeException("Exception");
        }
        return dataDao.insertSelective(order);
    }


    @Transactional
    @Override
    public Object addActualNumber(Order order) {
        Order order_ = dataDao.selectByPrimaryKey(order.getId());
        order.setActualNumber(order.getActualNumber().add(order_.getActualNumber()));
        order.setDeliverNumber(order_.getDeliverNumber().subtract(order.getNumber()));
        order.setNumber(order_.getNumber());
        logger.debug("order.getDeliverNumber()====" + order.getDeliverNumber());
        logger.debug("order.getNumber()====" + order.getNumber());
        logger.debug("order.getActualNumber()====" + order.getActualNumber());
        if (order.getDeliverNumber().compareTo(order.getNumber()) == 1 ||
                order.getActualNumber().compareTo(order.getNumber()) == 1 ||
                order.getActualNumber().compareTo(order.getDeliverNumber()) == 1) {
            throw new RuntimeException("数据有误，更新失败!");
        }
        if (order.getActualNumber().equals(order_.getNumber())) { // 实提数量等于订单数量，订单执行完成
            order.setDeliverStatus("1");
            order.setStatus(OrderConstants.STATUS_NORMAL_END);
            int re = dataDao.updateByPrimaryKeySelective(order);
        } else {
            if ((order.getNumber().compareTo(order.getActualNumber()) == 1 && (order.getActualNumber().compareTo(BigDecimal.valueOf(0.0)) == 1))) {
                order.setDeliverStatus("2");
            }
            dataDao.updateByPrimaryKeySelective(order);
        }
        return null;
    }

    @Override
    public int payOrderInBatch(List<Order> orders) {
        return dataDao.payOrderInBatch(orders);
    }


    /**
     * 不需要事务管理的
     *
     * @param user
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public int queryCount(OrderVo user) {
        return dataDao.queryCount(user);
    }

    @Override
    public int queryMyOrderCount(OrderVo user) {
        return dataDao.queryMyOrderCount(user);
    }


    /**
     * 已收款金额变化
     *
     * @param id
     * @param received
     * @return
     */
    @Override
    public int changeMoneyNumber(Integer id, BigDecimal received) {
        Order order = dataDao.selectByPrimaryKey(id);
        Order order1 = new Order();
        order1.setId(id);

        order1.setActualReceived(order.getActualReceived().add(received));

        BigDecimal payStatus = order.getActualTotal().subtract(order1.getActualReceived().abs());
        if (order1.getActualReceived().compareTo(BigDecimal.ZERO) == -1) {
            throw new RuntimeException("退款数据错误");
        }
        if (payStatus.compareTo(BigDecimal.ZERO) == 0) {
            order1.setPayStatus("1"); // 已付款
        } else if (payStatus.compareTo(BigDecimal.ZERO) == -1) {
            throw new RuntimeException("付款数据错误");
        } else if (payStatus.compareTo(BigDecimal.ZERO) == 1) {
            if (payStatus.compareTo(order.getActualTotal()) == 0) {
                order1.setPayStatus("0");
            } else if (payStatus.compareTo(order.getActualTotal()) == 1) {
                throw new RuntimeException("付款数据错误");
            } else if (payStatus.compareTo(order.getActualTotal()) == -1) {
                order1.setPayStatus("2"); // 部分付款
            }
        }
        return dataDao.updateByPrimaryKeySelective(order1);
    }

    @Override
    public int changeNumber(Integer id, BigDecimal receiving, BigDecimal received) {
        Order order = dataDao.selectByPrimaryKey(id);
        Order order1 = new Order();
        order1.setId(id);
        order1.setActualNumber(order.getActualNumber().add(received));
        order1.setDeliverNumber(order.getDeliverNumber().add(receiving)); //

        if (order1.getDeliverNumber().compareTo(BigDecimal.ZERO) == -1 ||
                order1.getDeliverNumber().compareTo(order.getNumber()) == 1 ||
                order1.getActualNumber().compareTo(BigDecimal.ZERO) == -1 ||
                order1.getActualNumber().compareTo(order.getNumber()) == 1) {
            throw new RuntimeException("数据错误");
        }
        if (order1.getDeliverNumber().compareTo(order.getNumber()) == -1) {
            order1.setDeliverStatus("1"); // 部分收货
        } else if (order1.getDeliverNumber().compareTo(order.getNumber()) == 0) {
            order1.setDeliverStatus("2"); // 完全收货
        }
        return dataDao.updateByPrimaryKeySelective(order1);
    }


    @Override
    public int updateCartShopNum(OrderShop arg) {
        return orderShopService.updateNum(arg.getId(), arg.getNumber());
    }


    @Override
    public List<OrderVo> ongoGroupshoping(OrderShop arg) {
        return null;
    }

    @Override
    public List<OrderVo> selectGroupOrder(OrderVo arg) {
        return dataDao.selectGroupOrder(arg);
    }

    @Override
    public int countWithOfferByPage(OrderVo user) {
        return dataDao.countWithOfferByPage(user);
    }

    @Override
    public List<OrderVo> queryWithOfferByPage(OrderVo user) {
        return dataDao.queryWithOfferByPage(user);
    }
}
